'''
design
'''
import time
import hashlib
import pickle

###################################################################################
def singleton(cls):
	'''
	Make a class to be a singleton
	'''
	assert isinstance(cls, type), 'cls must be an class'

	instances	= {}
	def __getinstance(*args, **kwds):
		if cls not in instances:
			instances[cls]	= cls(*args, **kwds)
		return instances[cls]
	return __getinstance

###################################################################################
def costtime(f):
	'''
	add an costtime attribute when run f(*args)
	'''
	import time
	def newf(*args):
		start			= time.time()
		f(*args)
		newf.costtime	= time.time() - start
	
	newf.__name__		= f.__name__
	newf.costtime		= 0
	return newf

###################################################################################
# def cache(duration= 10):
#     caches	= {}
#     def get_key(function, *args, **kw):
#         key	= pickle.dumps((function.__name__, args, kw))
#         return hashlib.sha1(key).hexdigest()

#     def _cache(function):
#         def __cache(*args, **kw):
#             key	= get_key(function, args, kw)
#             if key in caches:
#                 current	= time.time()
#                 item	= caches[key]
#                 is_obsolete	= current - item['time'] > duration
#                 if not is_obsolete:
#                     # print('in cache')
#                     return item['value']

#             # print('not in cache')
#             result		= function(*args, **kw)
#             caches[key]	= {'value':result, 'time':time.time()}
#             return result
#         return __cache
#     return _cache


# @cache(5)
# def test(num):
#     time.sleep(3)
#     return num * num

# print(test(10))
# print(test(3))
# print(test(10))
